package com.example.dicomviewer;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.example.dicomviewer.core.DataArray;
import com.example.dicomviewer.photoview.PhotoView;
import com.example.dicomviewer.reconstruction.Reconstruction;

import java.util.ArrayList;

/*
 * 显示序列的界面,可以查看图片,缩放,和查看图片信息
 * */
public class ViewerActivity extends AppCompatActivity implements View.OnClickListener {

    enum ViewType {
        Axial, Coronal, Sagittal
    }

    private final String TAG = "ViewerActivity";
    DicomInfo dicomInfo;

    SeekBar seekBar;
    PhotoView iv;
    int number = 0;
    // 图片的 Uri 序列
    ArrayList<String> data;
    // 序列的像素数组
    int[][][] pixels;
    ViewType viewType;
    int axialCursor = 0, coronalCursor = 0, sagittalCursor = 0;
    int axialSize = 0, coronalSize = 0, sagittalSize = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_viewer);
        Intent intent = getIntent();
        data = intent.getStringArrayListExtra("dir_array");
        Log.d(TAG, data.toString());
        reset();

        loadSeriseToInts();

        iv = (PhotoView) findViewById(R.id.iv);
        seekBar = (SeekBar) findViewById(R.id.cursor_seek_bar);
        Button button_next = (Button) findViewById(R.id.button_next);
        Button button_previous = (Button) findViewById(R.id.button_previous);
        Button changeViewType = (Button) findViewById(R.id.change_view_type);
        Button reconstruction = (Button) findViewById(R.id.reconstruction);

        button_next.setOnClickListener(this);
        button_previous.setOnClickListener(this);
        changeViewType.setOnClickListener(this);
        reconstruction.setOnClickListener(this);

        initEvent();
        if (data.size() == 0) {
            iv.setImageResource(R.drawable.file_not_found);
            button_previous.setVisibility(View.INVISIBLE);
            button_next.setVisibility(View.INVISIBLE);
            Toast.makeText(this, "此文件夹下无dicom文件", Toast.LENGTH_SHORT).show();
        } else {
            changePicture(0);
//            updateViewAndInfo(data.get(number));
        }
    }

    void initEvent() {
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (viewType == ViewType.Axial) {
                    axialCursor = progress;
                } else if (viewType == ViewType.Coronal) {
                    coronalCursor = progress;
                } else {
                    sagittalCursor = progress;
                }
                changePicture(0);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

    }

    private void reset() {
        this.viewType = ViewType.Axial;
        this.axialCursor = 0;
        this.coronalCursor = 0;
        this.sagittalCursor = 0;
    }

    private void changeViewType() {
        if (this.viewType == ViewType.Axial) {
            this.viewType = ViewType.Coronal;
        } else if (this.viewType == ViewType.Coronal) {
            this.viewType = ViewType.Sagittal;
        } else {
            this.viewType = ViewType.Axial;
        }
        changePicture(0);
    }

    private Bitmap pathToBitmap(String path) {
        Uri uri = Uri.parse(path);
        String truePath = FileInfoUtils.getPath(this, uri);
        return DicomFileReader.readFileBitMap(truePath);
    }

    private void loadSeriseToInts() {
        Log.d(TAG, "Begin load series to int[]");
        if (data == null || data.isEmpty()) {
            return;
        }
        Bitmap firstBitmap = pathToBitmap(data.get(0));
        int height = firstBitmap.getHeight();
        int width = firstBitmap.getWidth();
        this.axialSize = data.size();
        this.coronalSize = width;
        this.sagittalSize = height;
        Log.d(TAG, "height: " + height);
        Log.d(TAG, "width: " + width);
        this.pixels = new int[data.size()][height][width];
        long loadStartTime = SystemClock.elapsedRealtime();
        for (int i = 0; i < data.size(); ++i) {
            Bitmap bitmap = pathToBitmap(data.get(i));

            // 总共 load time: 2586 ms
            int[] pixels = new int[width * height];
            bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
            for (int j = 0; j < pixels.length; j++) {
                // 顺时针旋转画面90度
                this.pixels[i][j % width][j / width] = pixels[j];
            }

            // 总共 load time: 14707 ms
//            for (int j = 0; j < width; ++j) {
//                for (int k = 0; k < height; ++k) {
//                    this.pixels[i][j][k] = bitmap.getPixel(j, k);
//                }
//            }
        }
        DataArray dataArray = DataArray.getInstance();
        // 注意初始化顺序，需要先初始化三个维度，然后再初始化像素
        dataArray.setSliceSize(data.size());
        dataArray.setHight(height);
        dataArray.setWidth(width);
        dataArray.setPixel(pixels);
        Log.d(TAG, "load time: " + (SystemClock.elapsedRealtime() - loadStartTime) + " ms");
        Log.d(TAG, "load series to int[] success");
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.infomation:
                if (viewType != ViewType.Axial) {
                    Toast.makeText(this, "当前不是轴位图，无法查看信息", Toast.LENGTH_SHORT).show();
                } else {
                    String truePath = FileInfoUtils.getPath(this, Uri.parse(this.data.get(this.axialCursor)));
                    this.dicomInfo = DicomFileReader.readFileInfo(truePath);
                    if (dicomInfo != null) {
                        AlertDialog.Builder dialog = new AlertDialog.Builder(this);
                        dialog.setTitle("详细信息");
                        dialog.setMessage(dicomInfo.toString());
                        dialog.setCancelable(true);    //设置是否可以通过点击对话框外区域或者返回按键关闭对话框
                        dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                            }
                        });
                        dialog.show();
                    } else {
                        Toast.makeText(this, "无法读取文件信息", Toast.LENGTH_SHORT).show();
                    }
                }
                break;
            default:
        }
        return true;
    }

    public void updateImg(Bitmap bitmap) {
        if (bitmap != null) {
            iv.setImageBitmap(bitmap);
        } else {
//            可以换成一个报错的界面
            Log.d(TAG, "update IMG ERROR, bitmap is null");
            iv.setImageResource(R.drawable.file_not_found);
        }
    }


    public void updateImgInfo(DicomInfo dicomInfo) {
        this.dicomInfo = dicomInfo;
    }


    // 点击 “上一个” 按钮后的操作
    public void displayPreviousImg() {
        changePicture(-1);
    }

    // 点击 “下一个” 按钮后的操作
    public void displayNextImg() {
        //加载图片
        changePicture(1);
    }

    // step 是步长，如果是0表示刷新，如果是1，表示
    private void changePicture(int step) {
        Log.d(TAG, "begin change picture,step = " + step);
        iv.setImageResource(R.drawable.file_not_found);
        Bitmap bitmap = null;
        if (this.viewType == ViewType.Axial) {
            bitmap = Bitmap.createBitmap(this.coronalSize, this.sagittalSize, Bitmap.Config.ARGB_8888);
            this.axialCursor = (this.axialCursor + step + this.axialSize) % this.axialSize;
            seekBar.setProgress(axialCursor);
            seekBar.setMax(axialSize);
            for (int y = 0; y < coronalSize; ++y) {
                for (int z = 0; z < sagittalSize; ++z) {
                    bitmap.setPixel(y, z, this.pixels[axialCursor][y][z]);
                }
            }
        } else if (this.viewType == ViewType.Coronal) {
            bitmap = Bitmap.createBitmap(this.sagittalSize, this.axialSize, Bitmap.Config.ARGB_8888);
            this.coronalCursor = (this.coronalCursor + step + this.coronalSize) % this.coronalSize;
            seekBar.setProgress(coronalCursor);
            seekBar.setMax(coronalSize);
            for (int z = 0; z < sagittalSize; ++z) {
                for (int x = 0; x < axialSize; ++x) {
                    bitmap.setPixel(z, x, this.pixels[x][coronalCursor][z]);
                }
            }
        } else if (this.viewType == ViewType.Sagittal) {
            bitmap = Bitmap.createBitmap(this.coronalSize, this.axialSize, Bitmap.Config.ARGB_8888);
            this.sagittalCursor = (this.sagittalCursor + step + this.sagittalSize) % this.sagittalSize;
            seekBar.setProgress(sagittalCursor);
            seekBar.setMax(sagittalSize);
            for (int y = 0; y < coronalSize; ++y) {
                for (int x = 0; x < axialSize; ++x) {
                    bitmap.setPixel(y, x, this.pixels[x][y][sagittalCursor]);
                }
            }
        }
        updateImg(bitmap);
        Log.d(TAG, "end change picture");
    }


    // 目前处理 file:/ 开头的没问题
    void updateViewAndInfo(String filePath) {
        Log.d(TAG, filePath);
        Uri uri = Uri.parse(filePath);
//        String testFileName = this.getExternalCacheDir() + "/" + fileName;
//        Log.d("MyActivity", "is file path: " + getAssets());
        String truePath = FileInfoUtils.getPath(this, uri);
        updateImg(DicomFileReader.readFileBitMap(truePath));
        updateImgInfo(DicomFileReader.readFileInfo(truePath));
    }

    void updateViewAndInfo(Bitmap bitmap) {
        updateImg(bitmap);
    }


    private void startReconstruction() {
        Log.d(TAG, "start Reconstruction");
//      max value: -1
//      min value: -16777216
//      pixel size is 512*512*100 *4B = 100 MB

        // 使用 DataArray 进行传递
        Intent intent = new Intent(ViewerActivity.this, Reconstruction.class);
        startActivity(intent);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button_next:
                Log.d("button_next", "button_next clicked");
                displayNextImg();
                break;
            case R.id.button_previous:
                Log.d("button_previous", "button_previous clicked");
                displayPreviousImg();
                break;
            case R.id.change_view_type:
                Log.d(TAG, "change_view_type clicked");
                changeViewType();
                break;
            case R.id.reconstruction:
                Log.d(TAG, "reconstruction clicked");
                startReconstruction();
                break;
        }
    }

}